using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

using Nairo.Parser;
using Nairo.Parser.Dom;

namespace Nairo
{
	public partial class HtmlPanel : UserControl
	{
		protected bool bIgnoreScrolling;
		protected Bitmap myBitmap;
		protected FileUnit file;
		
		public delegate void LinkClickHandler(object HTMLPanel, HtmlEventArgs htmlEventInfo);
		
		public event LinkClickHandler OnLinkClick;
		
		public HtmlPanel()
		{
			InitializeComponent();
			bIgnoreScrolling=false;
			file = new FileUnit();
		}

		protected void Render()
		{
			Stopwatch watch = new Stopwatch();
			watch.Start();

			this.myRenderer = Nairo.LayoutEngine.LayoutDocument(this.file, this.Width - 20);
			
			if((myRenderer.Width==0)||(myRenderer.Height==0))return;
			myBitmap=new Bitmap(myRenderer.Width,myRenderer.Height);
			Graphics g=Graphics.FromImage(myBitmap);
			g.Clear(TypeConverter.ConvertColor(file.Body.GetAttributeValue("background-color"), Color.White));
			myRenderer.Paint(g);

			this.pictureBox1.Width=myBitmap.Width;
			this.pictureBox1.Height=myBitmap.Height;
			this.pictureBox1.Image=myBitmap;
			this.pictureBox1.Top=0;
			this.pictureBox1.Left=0;

			SizeScrollBars();
			
			watch.Stop();
			
			Debug.Print("Rendering needed " + watch.ElapsedMilliseconds + " ms!");
		}
		
		public void OpenFile(string fileName)
		{
			HTMLParser parser = new HTMLParser(fileName, new StreamReader(fileName).ReadToEnd());
			parser.Parse();
			this.file = parser.CurrentFile;
			this.Render();
		}

		public string GetRendererInfo()
		{
			return myRenderer.ToString();
		}

		private void HTMLPanel_Resize(object sender, EventArgs e)
		{
			this.Render();
			SizeScrollBars();
		}

		public void SizeScrollBars()
		{
			bIgnoreScrolling=true;

			if(this.myRenderer==null)
			{
				hScrollBar.Enabled=false;
				vScrollBar.Enabled=false;
			}


			this.hScrollBar.Value=0;
			this.vScrollBar.Value=0;

			if(this.myRenderer!=null)
			{
				if(myRenderer.Height>this.Height)
				{
					vScrollBar.Value=0;
					vScrollBar.Maximum=myRenderer.Height - 16;
					vScrollBar.SmallChange=10;
					vScrollBar.LargeChange=myRenderer.Height / 10;
					vScrollBar.Enabled=true;
				}
				else
				{
					vScrollBar.Enabled=false;
				}

				int hWidth=this.Width;
				if(vScrollBar.Visible) hWidth-=16;

				if(myRenderer.Width>hWidth - 16)
				{
					hScrollBar.Value=0;
					hScrollBar.Maximum=myRenderer.Width-this.Width+16+16+16;
					hScrollBar.SmallChange=10;
					hScrollBar.LargeChange=myRenderer.Width / 2;
					hScrollBar.Enabled=true;
				}
				else
				{
					hScrollBar.Enabled = false;
				}

			}

			bIgnoreScrolling=false;
		}
		
		protected override void OnMouseWheel(MouseEventArgs e)
		{
			int scrollValue = vScrollBar.Value - e.Delta / 2;
			
			if (scrollValue < 0)
				scrollValue = 0;
			
			if (scrollValue > vScrollBar.Maximum)
				scrollValue = vScrollBar.Maximum;
			
			vScrollBar.Value = scrollValue;
			
			base.OnMouseWheel(e);
		}

		private void myHScrollBar_ValueChanged(object sender, EventArgs e)
		{
			if(bIgnoreScrolling) return;
			this.pictureBox1.Left=-hScrollBar.Value;
			this.Invalidate();
		}

		private void myVScrollBar_ValueChanged(object sender, EventArgs e)
		{
			if(bIgnoreScrolling) return;
			this.pictureBox1.Top=-vScrollBar.Value;
//			this.pictureBox1.Update();
//			this.pictureBox1.Image=this.myBitmap;
			this.Invalidate();
		}
		
		private void myPictureBox_MouseDown(object sender, MouseEventArgs e)
		{
//			Check to see if mouse was pressed down on
//			a hyperlink
			int docx=e.X;
			int docy=e.Y;
			RenderItem item=this.myRenderer.LocateItem(docx,docy);
			this.Focus();
//			 TODO : Implement checking for links

		}
		
		void PictureBox1MouseMove(object sender, MouseEventArgs e)
		{
			this.Focus();
		}
	}
}